package com.bt.framework.ext

import android.graphics.Color
import android.graphics.Typeface
import android.text.Spannable
import android.text.SpannableString
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.BackgroundColorSpan
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.text.style.RelativeSizeSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
import android.view.View
import android.widget.TextView

/**
 *@author:hxm
 *@date: 2025/6/23 21:46
 *@version:
 *@description: Span扩展
 */

/**
 * 将一段文字中指定range的文字改变大小
 * @param range 要改变大小的文字的范围
 * @param scale 缩放值，大于1，则比其他文字大；小于1，则比其他文字小；默认是1.5
 */
fun CharSequence.toSizeSpan(range: IntRange, scale: Float = 1.5f): SpannableString {
    return SpannableString(this).apply {
        setSpan(
            RelativeSizeSpan(scale),
            range.first,
            range.last,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        )
    }
}

/**
 * 将一段文字中指定range的文字改变前景色
 * @param range 要改变前景色的文字的范围
 * @param color 要改变的颜色，默认是红色
 */
fun CharSequence.toColorSpan(range: IntRange, color: Int = Color.RED): SpannableString {
    return SpannableString(this).apply {
        setSpan(
            ForegroundColorSpan(color),
            range.first,
            range.last,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        )
    }
}

/**
 * 将一段文字中指定range的文字改变背景色
 * @param range 要改变背景色的文字的范围
 * @param color 要改变的颜色，默认是红色
 */
fun CharSequence.toBackgroundColorSpan(range: IntRange, color: Int = Color.RED): SpannableString {
    return SpannableString(this).apply {
        setSpan(
            BackgroundColorSpan(color),
            range.first,
            range.last,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        )
    }
}

/**
 * 将一段文字中指定range的文字添加删除线
 * @param range 要添加删除线的文字的范围
 */
fun CharSequence.toStrikeThroughSpan(range: IntRange): SpannableString {
    return SpannableString(this).apply {
        setSpan(StrikethroughSpan(), range.first, range.last, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    }
}

/**
 * 将一段文字中指定range的文字添加颜色和点击事件
 * @param range 目标文字的范围
 */
fun CharSequence.toClickSpan(
    range: IntRange, color: Int = Color.RED,
    isUnderlineText: Boolean = false, clickAction: () -> Unit
): SpannableString {
    return SpannableString(this).apply {
        val clickableSpan = object : ClickableSpan() {

            override fun onClick(widget: View) {
                clickAction()
            }

            override fun updateDrawState(ds: TextPaint) {
                ds.color = color
                ds.isUnderlineText = isUnderlineText
            }

        }
        setSpan(clickableSpan, range.first, range.last, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    }
}

/**
 * 将一段文字中指定range的文字添加style效果
 * @param range 要添加删除线的文字的范围
 */
fun CharSequence.toStyleSpan(range: IntRange, style: Int = Typeface.BOLD): SpannableString {
    return SpannableString(this).apply {
        setSpan(StyleSpan(style), range.first, range.last, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    }
}

/**
 * 将一段文字中指定range的文字改变大小
 * @param str 要改变大小的文字
 * @param range 要改变大小的文字的范围
 * @param scale 缩放值，大于1，则比其他文字大；小于1，则比其他文字小；默认是1.5
 */
fun TextView.sizeSpan(str: String = "", range: IntRange, scale: Float = 1.5f): TextView {
    text = (if (str.isEmpty()) text else str).toSizeSpan(range, scale)
    return this
}

/**
 * 将一段文字中指定range的文字改变大小
 * @param str 要改变大小的文字
 * @param scale 缩放值，大于1，则比其他文字大；小于1，则比其他文字小；默认是1.5
 */
fun TextView.appendSizeSpan(str: String = "", scale: Float = 1.5f): TextView {
    append(str.toSizeSpan(0..str.length, scale))
    return this
}

/**
 * 将一段文字中指定range的文字改变前景色
 * @param str 要改变前景色的文字
 * @param range 要改变前景色的文字的范围
 * @param color 要改变的颜色，默认是红色
 */
fun TextView.colorSpan(str: String = "", range: IntRange, color: Int = Color.RED): TextView {
    text = (str.ifEmpty { text }).toColorSpan(range, color)
    return this
}

/**
 * 将一段文字中指定range的文字改变前景色
 * @param str 要改变前景色的文字
 * @param range 要改变前景色的文字的范围
 * @param color 要改变的颜色，默认是红色
 */
fun TextView.appendColorSpan(str: String = "", color: Int = Color.RED): TextView {
    append(str.toColorSpan(0..str.length, color))
    return this
}

/**
 * 将一段文字中指定range的文字改变前景色
 * @param str 要改变前景色的文字
 * @param range 要改变前景色的文字的范围
 * @param color 要改变的颜色，默认是红色
 */
fun TextView.backgroundColorSpan(
    str: String = "",
    range: IntRange,
    color: Int = Color.RED
): TextView {
    text = (str.ifEmpty { text }).toBackgroundColorSpan(range, color)
    return this
}

/**
 * 将一段文字中指定range的文字改变前景色
 * @param str 要改变前景色的文字
 * @param color 要改变的颜色，默认是红色
 */
fun TextView.appendBackgroundColorSpan(str: String = "", color: Int = Color.RED): TextView {
    append(str.toBackgroundColorSpan(0..str.length, color))
    return this
}

/**
 * 将一段文字中指定range的文字改变前景色
 * @param str 要改变前景色的文字
 * @param range 要改变前景色的文字的范围
 */
fun TextView.strikeThroughSpan(str: String = "", range: IntRange): TextView {
    text = (str.ifEmpty { text }).toStrikeThroughSpan(range)
    return this
}

/**
 * 将一段文字中指定range的文字添加删除线
 * @param str 要添加删除线的文字
 */
fun TextView.appendStrikeThroughSpan(str: String = ""): TextView {
    append(str.toStrikeThroughSpan(0..str.length))
    return this
}

/**
 * 将一段文字中指定range的文字添加颜色和点击事件
 * @param str 要添加颜色和点击事件的文字
 * @param range 要添加颜色和点击事件的文字的范围
 * @param color 要添加的颜色，默认是红色
 * @param isUnderlineText 是否添加下划线，默认是false
 * @param clickAction 点击事件
 */
fun TextView.clickSpan(
    str: String = "", range: IntRange,
    color: Int = Color.RED, isUnderlineText: Boolean = false,
    clickAction: () -> Unit
): TextView {
    movementMethod = LinkMovementMethod.getInstance()
    highlightColor = Color.TRANSPARENT
    text = (str.ifEmpty { text }).toClickSpan(range, color, isUnderlineText, clickAction)
    return this
}

/**
 * 将一段文字中指定range的文字添加颜色和点击事件
 * @param str 要添加颜色和点击事件的文字
 * @param range 要添加颜色和点击事件的文字的范围
 * @param color 要添加的颜色，默认是红色
 * @param isUnderlineText 是否添加下划线，默认是false
 * @param clickAction 点击事件
 */
fun TextView.appendClickedSpan(
    str: String = "", range: IntRange,
    color: Int = Color.RED, isUnderlineText: Boolean = false,
    clickAction: () -> Unit
): TextView {
    movementMethod = LinkMovementMethod.getInstance()
    highlightColor = Color.TRANSPARENT
    append(str.toClickSpan(0..str.length, color, isUnderlineText, clickAction))
    return this
}

/**
 * 添加style效果
 * @param str 要添加style效果的文字
 * @param range 要添加style效果的文字的范围
 * @param style 样式，默认是加粗
 */
fun TextView.styleSpan(str: String = "", range: IntRange, style: Int = Typeface.BOLD): TextView {
    text = (str.ifEmpty { text }).toStyleSpan(range, style)
    return this
}

/**
 * 添加style效果
 * @param str 要添加style效果的文字
 * @param style 样式，默认是加粗
 */
fun TextView.appendStyleSpan(str: String = "", style: Int = Typeface.BOLD): TextView {
    append(str.toStyleSpan(0..str.length, style))
    return this
}